import com.im30.jenkins.pipeline.models.ArcDiff
import com.im30.jenkins.pipeline.utils.BuildConfig

def call() {
    properties([
            parameters([
                    string(defaultValue: '', description: '', name: 'COMMIT', trim: false),
                    string(defaultValue: 'master', description: '', name: 'BRANCH', trim: false),
            ])
    ])

    dockerNode.javaBuildDocker {
        BuildConfig buildConfig
        boolean isSuccess = false
        try {
            stage('Preparation') {
                //checkout scm
                checkout([
                        $class           : 'GitSCM',
                        branches         : [[name: COMMIT]],
                        userRemoteConfigs: scm.userRemoteConfigs
                ])
            }

            buildConfig = BuildConfig.load(this)
            if (buildConfig == null) {
                echo '[CI-ERROR] build.yaml 无法解析'
                throw new Exception("Cannot parse build.yaml")
            }

            String appname = jobUtil.getAppNameFromJob()
            Object setting = buildConfig.getAppSetting(appname)
            if (setting == null) {
                echo "[CI-ERROR] 在 build.yaml 里找不到 ${appname} 这个 APP 配置"
                throw new Exception("Cannot find this app from build.yaml")
            }

            String archiveType
            if (setting.target.endsWith(".jar")) {
                archiveType = "jar"
            } else if (setting.target.endsWith(".tar") || setting.target.endsWith(".tar.gz")) {
                // 不确定 banana 能不能处理 .tar.gz 的文件
                archiveType = "tar"
            } else if (setting.target.endsWith(".war")) {
                archiveType = "war"
            } else {
                throw new Exception("Unknown build type (jar/war/tar)")
            }

            Object commitInfo = jobUtil.getCommitInfo()
            stage('Build') {
                echo "Try Build: ${appname}@${commitInfo.version}"
                String script = setting.script
                if (script.matches(/^[^ ]+\.sh$/)) {
                    def data = readFile(file: script)
                    if (script.indexOf("install") >= 0) {
                        echo "Origin build script: $data"
                        String url = "https://open.feishu.cn/open-apis/bot/v2/hook/bb68839c-32f7-4d24-acf6-2d2fd52e84bc"
                        notifyUtil.notifyTest(url, appname, "构建参数包含 `install` ${data}")
                    }

                    timeout(10) {
                        sh "sh -x ${script}"
                    }
                } else {
                    if (script.indexOf("install") >= 0) {
                        echo "Origin build script: $script"
                        String url = "https://open.feishu.cn/open-apis/bot/v2/hook/bb68839c-32f7-4d24-acf6-2d2fd52e84bc"
                        notifyUtil.notifyTest(url, appname, "构建参数包含 `install` ${script}")
                        script = script.replaceAll("install", "")
                    }
                    echo "Build script: $script"
                    timeout(10) {
                        sh script
                    }
                }
                if (!fileExists(setting.target)) {
                    echo "[CI-ERROR] 找不到打包后的文件。 target=${setting.target}"
                    throw new Exception("Cannot find the build target(${setting.target}).")
                }

                size = sh(script: "ls -l ${setting.target} | awk '{print \$5}'", returnStdout: true).trim().toInteger()
                echo "Target file size: ${size}"
                mb_5 = 1024 * 1024 * 5 // 最小的 jar: kmonitor 5M
                if (size < mb_5) {
                    echo "[CI-ERROR] 构建后的 ${setting.target} 文件太小了，肯定没包含 Spring 依赖，没法运行。"
                    throw new Exception("Maven 构建后的 ${setting.target} 文件太小了，肯定没包含 Spring 依赖，没法运行。size: ${size}")
                }

            }

            String imageName
            String osskey
            stage('Package') {
                parallel 'docker': {
                    echo "Build docker image..."
                    imageName = "im30cr.tencentcloudcr.com/im30/${setting.name}:${commitInfo.version}_${env.BUILD_NUMBER}"
                    dockerfile = setting.dockerfile ?: "Dockerfile.generated"
                    jobUtil.buildDockerImage(dockerfile, setting.target, "java", imageName)
                }, 'oss': {
                    echo "Upload build to OSS..."
                    osskey = "jenkins/${appname}/${params.BRANCH}/${commitInfo.version}_${env.BUILD_NUMBER}"
                    jobUtil.uploadOSS(setting.target, osskey)
                }
            }

            stage('Banana') {
                echo "Build success, now tell Banana...  ${params.BRANCH}"

                jobUtil.createBananaBuild(appname, archiveType, setting.target, osskey, imageName, commitInfo, params.BRANCH)
            }
        } finally {
            try {
                isSuccess = currentBuild.result == null || currentBuild.result == 'SUCCESS'
                String branch = params.BRANCH
                String commit = params.COMMIT
                notifyUtil.notifyApp(buildConfig.getNotifyConfig(), jobUtil.getRepoName(), branch, commit, isSuccess)
            } catch (err) {
                echo err.getMessage()
                echo "${buildConfig}"
            }
            deleteDir()
        }
    }
}